// src/config.rs
use std::error::Error;
use std::fs;
use serde::Deserialize;
use toml::Value;

#[derive(Debug, Deserialize, Clone)]
#[serde(rename_all = "lowercase")]
pub enum ConfigType {
    Provider,
    Visitor
}

#[derive(Debug, Deserialize, Clone)]
pub struct ServerConfig {
    pub address: String,
    pub port: u16
}

#[derive(Debug, Deserialize, Clone)]
pub struct ClientConfig {
    pub name:String,
    pub bind_addr: String,
    pub bind_port: u16
}

#[derive(Debug, Deserialize, Clone)]
pub struct Config {
    pub config_type: ConfigType,
    pub server: ServerConfig,
    pub client: ClientConfig
}

pub fn load_config() -> Result<Config, Box<dyn Error>> {
    let content = fs::read_to_string("conf.toml")?;
    let config: Value = toml::from_str(&content)?;

    let err = || Box::<dyn Error>::from("server 配置缺失");
    // 获取 server 配置
    let server_config: ServerConfig = config.get("server")
        .and_then(|v| v.clone().try_into().ok())
        .ok_or_else(err)?;


    // 根据 config_type 决定是 visitor 还是 provider
    let client_config: ClientConfig;
    if config.get("provider").is_some() {
        client_config = config.get("provider")
            .and_then(|v| v.clone().try_into().ok())
            .ok_or_else(err)?;
        Ok(Config {
            config_type: ConfigType::Provider,
            server: server_config,
            client: client_config,
        })
    } else if config.get("visitor").is_some() {
        client_config = config.get("visitor")
            .and_then(|v| v.clone().try_into().ok())
            .ok_or_else(err)?;
        Ok(Config {
            config_type: ConfigType::Visitor,
            server: server_config,
            client: client_config,
        })
    } else {
        Err(Box::from("配置文件格式错误: 缺少 visitor 或 provider 配置"))
    }
}
